package conf

import (
	"fmt"
	"gitee.com/sourcandy/starter"
	"github.com/go-redis/redis"
	"github.com/goccy/go-json"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
	"reflect"
	"strings"
	"time"
)

func bindConfig(h interface{})  {
	ht := reflect.TypeOf(h).Elem()
	hv := reflect.ValueOf(h).Elem()
	if ht.Kind()== reflect.Struct {
		for i := 0; i < ht.NumField(); i++ {
			newT := ht.Field(i)
			newTFieldName := strings.ToLower(newT.Name)
			FileData := ReadConfig[newTFieldName].(map[string]interface{})
			ne := reflect.New(newT.Type.Elem())
			switch FileData["type"] {
				case starter.BindFileName:
					inFile(newT,ne,FileData)
				case starter.BindMysqlName:
					ne = inMysql(ne,FileData)
				case starter.BindRedisName:
					ne = inRedis(ne,FileData)
			default:
				panic("暂时不支持此类型赋值")
			}
			hv.Field(i).Set(ne)
		}
	}
}

func inRedis(ne reflect.Value,FileData map[string]interface{}) reflect.Value {
	data,_:=json.Marshal(FileData)
	config := RedisConfig{}
	json.Unmarshal(data,&config)
	addr := fmt.Sprintf("%s:%d",config.Host,config.Port)
	client := redis.NewClient(&redis.Options{
		PoolSize:     config.MaxActive,
		MinIdleConns:   config.MaxIdle,
		IdleTimeout: 2* time.Second,
		Addr:     addr, // Redis服务器地址和端口
		Password: config.Password,               // Redis密码（如果有的话）
		DB:       0,                // Redis数据库索引
	})
	ne = reflect.ValueOf(client)
	return ne
}

func inMysql(ne reflect.Value,FileData map[string]interface{}) reflect.Value {
	data,_:=json.Marshal(FileData)
	config := MysqlConfig{}
	json.Unmarshal(data,&config)
	var connStr = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local",
		config.User,
		config.Password,
		config.Host,
		config.Port,
		config.Name)
	db, err := gorm.Open(mysql.Open(connStr), &gorm.Config{
	})
	if err != nil {
		log.Printf("[info] gorm %s", err)
		panic("mysql连接失败")
	}
	ne = reflect.ValueOf(db)
	return ne
}

func inFile(newT reflect.StructField,ne reflect.Value,FileData map[string]interface{})  {
	for s := 0; s < newT.Type.Elem().NumField(); s++ {
		ss:=strings.ToLower(FileData[strings.ToLower(newT.Type.Elem().Field(s).Name)].(string))
		ne.Elem().FieldByName(newT.Type.Elem().Field(s).Name).Set(reflect.ValueOf(ss))
	}
}